﻿using log4net;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Hosting;
using Owin;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.Threading.Tasks;
using System.Xml.Linq;
using WPFExcelReport;
using INTEXReportSrv;
using WPFExcelReport.Helpers;
[ServiceBehavior(
    ConcurrencyMode = ConcurrencyMode.Multiple,
    InstanceContextMode = InstanceContextMode.Single)]
[assembly: OwinStartup(typeof(SignalRWindowsService.Startup))]
public partial class IntexReptServBL : IIntexReptServBL
{
    Dictionary<string, Agent> AgentList = new Dictionary<string, Agent>();
    string OracleDB = "user id=intex;password=intex;data source=intex1";
    bool IsStartListen = false;
    DataTable tbAgent;
    Int64 agents = 0;
    DataRow dwAgent;
    public Dictionary<string,object> ENVMAIN
    {
        get
        {
            return app.ENVMAIN(app.ServiceUri);
        }
    }
    ApplicationBase app
    {
        get
        {
            return ApplicationBase.Instance;
        }
    }
    
    public VICC_ZLAN VZL
    {
        get
        {
            if (!ENVMAIN.ContainsKey("VZL"))
            {
                ENVMAIN["VZL"] = new VICC_ZLAN();
            }
            return (VICC_ZLAN)ENVMAIN["VZL"];
        }
    }
    public ZLANServer VSK
    {
        get
        {
            if (!ENVMAIN.ContainsKey("VSK"))
            {
                ENVMAIN["VSK"] = new ZLANServer(25003);
            }
            return (ZLANServer)ENVMAIN["VSK"];
        }
    }
  public SignalRServer SignalRSrv
    {
        get
        {
            if (!ENVMAIN.ContainsKey("SignalRSrv"))
            {
                ENVMAIN["SignalRSrv"] = new SignalRServer(25008);
}
            return (SignalRServer)ENVMAIN["SignalRSrv"];
        }
    }
    public AMServer VSP
    {
        get
        {
            if (!ENVMAIN.ContainsKey("VSP"))
            {
                ENVMAIN["VSP"] = new AMServer(25007);
            }
            return (AMServer)ENVMAIN["VSP"];
        }
    }   
    bool ZLStartListen = false;
    public IntexReptServBL()
    {
        tbAgent = new DataTable();
        tbAgent.Columns.Add("AGENTID", typeof(string));
        tbAgent.Columns.Add("USERS", typeof(string));
        tbAgent.Columns.Add("MESSAGE", typeof(string));
        tbAgent.Columns.Add("SQLTEXT", typeof(string));
        tbAgent.Columns.Add("SQLPM", typeof(string));
        AgentList.Add("AGENTID-1", new Agent("-1"));
    }
    public Agent GetAgent(Dictionary<string, object> pm)
    {
        Agent agent = null;
        string agentid = "";
        try
        {
            if (pm.ContainsKey("AGENTID"))
            {
                agentid = (string)pm["AGENTID"];
                if (AgentList.ContainsKey(agentid))
                {
                    agent = AgentList[agentid];
                    agent.time = DateTime.Now;
                }
            }
        }
        catch (Exception ex)
        {
            LogHelper.error(ex.Message);
        }
        return agent;
    }
    public IDisposable SignalR { get; set; } 
    public ImageResult GetInfo(string para)
    {
        ImageResult result = new ImageResult();
        try
        {
            DataSet SReturn = null;
            string xmlString = "";
            XDocument xdoc = XDocument.Parse(para);
            Dictionary<string, object> listp = new Dictionary<string, object>();
            var items = from item in xdoc.Elements()
                        select item;
            List<XElement> clist = items.ToList<XElement>();
            foreach (XElement item in clist)
            {
                var itemsx = from itemx in item.Elements()
                             select itemx;
                foreach (XElement x in itemsx)
                {
                    listp.Add(x.Name.ToString(), (string)x.Value);
                }
            }
            string CommandType = listp["CommandType"].ToString();
            switch (CommandType)
            {
                case "RequestAgentStart":
                    SReturn = RequestAgentStart(listp);
                    result.str1 = "RequestAgentStart";
                    break;
                case "ZLANSTART":
                case "ZLANSET":
                    break;
                default:
                    SReturn = GetDataSetByQuery(listp);
                    if (SReturn.Tables.Count > 0)
                    {
                        result.str1 = SReturn.Tables[0].TableName;
                    }
                    break;
            }
            xmlString = SReturn.GetXml().ToString();
            result.str0 = xmlString;
        }
        catch (Exception ex)
        {
            LogHelper.error(ex.Message);
        }
        return result;
    }
   
 
    public DataSet GetDataSetByQuery(Dictionary<string, object> PM)
    {
        Agent agent = GetAgent(PM);
        DataSet dsResult = new DataSet();
        string pm = "";
        string sql = "";
        if (agent == null)
        {
            dsResult.DataSetName = "COMFAILED";
            return dsResult;
        }
        try
        {
            dsResult = agent.GetDataSetByQuery(PM);
            agent.CloseDB();
            foreach (KeyValuePair<string, object> kp in PM)
            {
                if (kp.Key == "CommandText")
                {
                    sql = (string)kp.Value;
                }
                else
                {
                    pm += kp.Key + ":" + kp.Value.ToString() + ";";
                }
            }
            LogHelper.info(sql + " With " + pm);
        }
        catch (Exception ex)
        {
            if (agent.IsOnTransation)
                agent.RollBack();
            DataTable tb = tbAgent.Clone();
            tb.TableName = "ERRORTB";
            dwAgent = tb.Rows.Add();
            dwAgent["AGENTID"] = agent.ID;
            dwAgent["USERS"] = "0";
            dwAgent["SQLTEXT"] = sql;
            dwAgent["MESSAGE"] = ex.Message;
            dwAgent["SQLPM"] = pm;
            dsResult.Merge(tb);
            LogHelper.error(ex.Message);
        }
        return dsResult;
    }
    public DataSet RequestAgentStart(Dictionary<string, object> pm)
    {
        DataSet dsResult = new DataSet();
        Agent agent = null;
        string agentid = "";
        try
        {
            if (pm.ContainsKey("QAGENT"))
            {
                agentid = (string)pm["QAGENT"];
                AgentList[agentid] = null;
                AgentList.Remove(agentid);
                LogHelper.info("QAGENT:" + agentid);
                dsResult = MagageAgent();
                return dsResult;
            } 
            if (pm.ContainsKey("CHKZLAPP"))
            {
              
                LogHelper.info("CHKZLAPP");
                if (!app.IsLoaded)
                {
                    app.Load(true);
                    dsResult = NewAgent();
                    foreach (DataRow row in dsResult.Tables[0].Rows)
                    {
                        app.proxy.AgentID = row["AGENTID"].ToString();
                        app.proxy.BYAGENT = true;
                    }
                }
                if (VZL == null)
                {
                }
                return dsResult;
            }
         
            if (pm.ContainsKey("SignalRSTART"))
            {
                if (!SignalRSrv.IsListening)
                {
                    LogHelper.info("SignalR");
                    SignalRSrv.StartListen();
                }
                else
                {
                    LogHelper.info("Listening already start");
                }  
                return dsResult;
            }
            if (pm.ContainsKey("ZLANSTART"))
            {
                if (!VSK.IsListening)
                {
                    LogHelper.info("ZLANSTART");
                    VSK.StartListen();
                }
                else
                {
                    LogHelper.info("Listening already start");
                }

                if (!VSP.IsListening)
                {
                    LogHelper.info("BOOKINGSTART");
                    VSP.InitSocketServer();

                }
                else
                {
                    LogHelper.info("Listening already start");
                }
                return dsResult;
            }

            if (pm.ContainsKey("ZLANCHK"))
            {

                DataTable tb = tbAgent.Copy();
                DataRow row = tb.Rows.Add();

                if (VSK.IsListening)
                {
                    row["SQLTEXT"] = "ZLANCHK";
                    row["MESSAGE"] = "STARTED";
                    LogHelper.info("Listening already start");
                }
                else
                {
                    row["SQLTEXT"] = "ZLANCHK";
                    row["MESSAGE"] = "ZLANSTART"; 
                    LogHelper.info("ZLANSTART"); 
                    VSK.StartListen();
                }
                if (VSP.IsListening)
                {
                    row["SQLTEXT"] = "ZLANCHK";
                    row["MESSAGE"] = "STARTED";
                    LogHelper.info("Listening already start");
                }
                else
                {
                    row["SQLTEXT"] = "ZLANCHK";
                    row["MESSAGE"] = "ZLANSTART";
                    LogHelper.info("ZLANSTART");
                    VSP.InitSocketServer();
                }
                dsResult.Merge(tb);
                return dsResult;
            }
            if (pm.ContainsKey("ZLANRESET"))
            {
                VSK.ZLResetListen();
                VSP.ZLResetListen();
                return dsResult;
            }
            if (pm.ContainsKey("ZLANSTOP"))
            {
                VSK.ZLStopListen();
                VSP.ZLStopListen();
                return dsResult;
            }

            if (pm.ContainsKey("ZLANSET"))
            {
                VSK.ZLSEND(pm);
                return dsResult;
            }

            if (pm.ContainsKey("ZLANGET"))
            {
                VSK.ZLREAD(pm);
                return dsResult;
            }
            if (pm.ContainsKey("ZLANSTOPAM"))
            {
                VSK.ZLSTOPAM(pm);
                return dsResult;
            }
            if (pm.ContainsKey("ITXCLSTART"))
            {
                VSK.ZLSTOPAM(pm);
                return dsResult;
            }
            dsResult = NewAgent();

        }
        catch (Exception ex)
        {
            LogHelper.error(ex.Message);
        }
        finally
        {
            //System.GC.Collect();
        }
        return dsResult;
    }
    public DataSet MagageAgent()
    {

        DataSet dsResult = new DataSet();
        DataTable tb = tbAgent.Copy();
        DataRow row = tb.NewRow();
        List<string> list = new List<string>();
        DateTime time = DateTime.Now;
        TimeSpan ts;
        foreach (KeyValuePair<string, Agent> ag in AgentList)
        {
            ts = time - ag.Value.time;
            if (ts.Minutes > 20)
            {
                list.Add(ag.Key);
            }
        }
        foreach (string ag in list)
        {
            AgentList[ag] = null;
            AgentList.Remove(ag);
        }
        row["AGENTID"] = "AGENTID" + agents;
        row["USERS"] = AgentList.Count;
        tb.Rows.Add(row);
        dsResult.Merge(tb);
        return dsResult;
    }

    public DataSet NewAgent()
    {
        MagageAgent();
        Agent agent = null;
        string agentid = "";
        DataSet dsResult = new DataSet();
        DataTable tb = tbAgent.Copy();
        DataRow row = tb.NewRow();

        agents++;
        agent = new Agent(agents.ToString());
        AgentList.Add("AGENTID" + agents, agent);
        row["AGENTID"] = "AGENTID" + agents;
        row["USERS"] = AgentList.Count;
        tb.Rows.Add(row);
        dsResult.Merge(tb);
        return dsResult;
    }
    public void StartAgentListen(Dictionary<string, object> dicSrcParamater)
    {
        Agent agent = null;
        string agentid = "";
        try
        {/*
            if (dicSrcParamater.ContainsKey("AGENTID"))
            {
                agentid = (string)dicSrcParamater["AGENTID"];
                if (AgentList.ContainsKey(agentid))
                {
                    agent = AgentList[agentid];
                    agent.time = DateTime.Now;
                    agent.CallBack = OperationContext.Current.GetCallbackChannel<IIntexReptServBLCallback>();
                    agent.IsListening = true;
                    if (!IsStartListen)
                    {
                        ListenTheQueue(agent.Connection);
                    }

                }
            }*/
        }
        catch (Exception ex)
        {
        }
    }
    void ListenTheQueue(string constr)
    {
        try
        {
            /*
            constr = constr.Replace(";Unicode=True;Persist Security Info=True;", "");
            OracleConnection con = new OracleConnection(constr);
            con.Open();
            // Prepare queue and provide the SUBSCRIPTION NAME
            OracleAQQueue queue = new OracleAQQueue("INTEX.STOCKQQ", con);
            queue.MessageType = OracleAQMessageType.Udt;
            queue.NotificationConsumers = new string[1] { "SUBSCRIBER1" };
            queue.MessageAvailable +=
              new OracleAQMessageAvailableEventHandler(MsgReceived);
            */
        }
        catch (Exception ex)
        {

            Console.WriteLine(ex.Message);
        }
    }

}
